import { useCallback, useMemo, useEffect, useRef } from "react"
import { atom, useAtomValue, getDefaultStore } from "jotai"
import { toast } from "react-toastify"
import _ from "lodash"

// 创建全局store实例
const globalStore = getDefaultStore()

// 定义错误类型枚举
type ErrType =
    | "internal" // 内部错误
    | "not_found" // 资源未找到
    | "validation" // 验证错误
    | "authentication" // 认证错误
    | "authorization" // 授权错误
    | "rate_limit" // 速率限制
    | "network" // 网络错误
    | "timeout" // 超时错误
    | "concurrency" // 并发错误

interface ErrorDetails {
    code: number
    message: string
    type: ErrType
}

type QueryType = TransactionApiTypes.Fetcher.Request.Params
type API = (params: QueryType) => Promise<TransactionApiTypes.Fetcher.Response.Result>
type Record = TransactionApiTypes.Fetcher.Response.Record

interface UseInfiniteFetchWithCursorProps {
    list: Record[] // 当前数据列表
    loading: boolean // 加载状态
    fetchData: (queryParam?: QueryType) => Promise<void> // 获取数据方法
    hasMore: boolean // 是否还有更多数据
    requestParams?: QueryType // 当前请求参数
    resetData: () => void // 重置数据方法
    error?: ErrorDetails // 错误信息
}

/**
 * 基于游标的分页数据获取Hook
 * @param api 数据获取API函数
 * @param initialParams 初始查询参数
 * @returns 包含数据列表、加载状态等信息的对象
 */
export default function useInfiniteFetchWithCursorAndPage(
    api: API,
    initialParams: QueryType,
): UseInfiniteFetchWithCursorProps {
    // 新增：稳定化initialParams
    const stableInitialParams = useMemo(() => initialParams, [initialParams])

    const listAtom = useMemo(() => atom<Record[]>([]), []) // 用于存解析后的list数据
    const loadingAtom = useMemo(() => atom(false), []) // 用于存储加载状态
    const hasMoreAtom = useMemo(() => atom(true), []) // 用于存储是否还有更多数据
    // eslint-disable-next-line react-hooks/exhaustive-deps
    const requestParamsAtom = useMemo(() => atom<QueryType>(stableInitialParams), []) // 用于存储请求参数
    const errorAtom = useMemo(() => atom<ErrorDetails>(), []) // 用于存储错误信息
    const currentPageAtom = useMemo(() => atom<number>(1), []) // 用于存储当前页码
    // 新增：用于存储请求ID
    const requestIdAtom = useMemo(() => atom<number>(0), [])

    /**
     * 获取数据方法
     * @param queryParam 查询参数
     */
    const fetchDataAtom = useMemo(
        () =>
            atom(null, async (get, set) => {
                // 使用get获取状态值
                const loading = get(loadingAtom)

                if (loading) return

                // 生成唯一请求ID
                const currentRequestId = Date.now()
                // 立即存储到全局store
                globalStore.set(requestIdAtom, currentRequestId)

                set(loadingAtom, true)
                try {
                    const params = {
                        page: get(currentPageAtom),
                        page_size: 10,
                        ...get(requestParamsAtom),
                    }

                    const response = await api(params)

                    // 只处理短时间内最新请求的响应
                    const latestRequestId = globalStore.get(requestIdAtom)
                    if (latestRequestId !== currentRequestId) return

                    const list = response?.list || []
                    const _total = response?.total || 0

                    // 计算是否还有更多数据
                    const _page = params.page
                    const _pageSize = params.page_size

                    const hasMore = _page * _pageSize < _total

                    set(listAtom, (prevList) => [...prevList, ...list])
                    set(hasMoreAtom, hasMore || false)
                    set(currentPageAtom, hasMore ? params.page + 1 : params.page)
                } catch (error) {
                    console.error("Error fetching data:", error)
                    set(loadingAtom, false)
                    set(errorAtom, error as ErrorDetails)
                    toast.error("Error fetching data.")
                } finally {
                    set(loadingAtom, false)
                }
            }),
        // eslint-disable-next-line react-hooks/exhaustive-deps
        [],
    )

    const resetData = useCallback(() => {
        globalStore.set(listAtom, [])
        globalStore.set(loadingAtom, false)
        globalStore.set(hasMoreAtom, true)
        globalStore.set(requestParamsAtom, stableInitialParams)
        globalStore.set(errorAtom, undefined)
        globalStore.set(currentPageAtom, 1)
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [stableInitialParams])

    const fetchData = useCallback(async () => {
        await globalStore.set(fetchDataAtom)
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [stableInitialParams])

    // 使用useAtom获取状态值
    const list = useAtomValue(listAtom)
    const loading = useAtomValue(loadingAtom)
    const hasMore = useAtomValue(hasMoreAtom)
    const requestParams = useAtomValue(requestParamsAtom)
    const error = useAtomValue(errorAtom)

    // 新增：使用深比较判断initialParams是否真的变化
    const initialParamsRef = useRef(stableInitialParams)
    useEffect(() => {
        if (!_.isEqual(initialParamsRef.current, stableInitialParams)) {
            initialParamsRef.current = stableInitialParams
            resetData()
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [stableInitialParams])

    useEffect(() => {
        fetchData()
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [requestParams])

    useEffect(() => {
        return () => {
            resetData()
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [])

    // 返回Hook提供的所有状态和方法
    return {
        list,
        loading,
        fetchData,
        hasMore,
        requestParams,
        resetData,
        error,
    }
}
